﻿using Microsoft.SqlServer.Server;
using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 线性标注
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SUDimensionLinearRef 的包装</remarks>
    public class DimensionLinear : Dimension
    {
        #region API 函数
        /// <summary>
        /// 创建线性标注
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="start_point">起点</param>
        /// <param name="start_path"><see cref="InstancePath"/> 起点引用物体</param>
        /// <param name="end_point">终点</param>
        /// <param name="end_path"><see cref="InstancePath"/> 终点引用物体</param>
        /// <param name="offset"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearCreate(out IntPtr dimension, Point3D start_point, IntPtr start_path, Point3D end_point, IntPtr end_path, double offset);

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="dimension"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearRelease(ref IntPtr dimension);

        /// <summary>
        /// 获取起点
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="point"></param>
        /// <param name="path"><see cref="InstancePath"/>起点引用物体</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetStartPoint(IntPtr dimension, ref Point3D point, out IntPtr path);

        /// <summary>
        /// 设置起点
        /// </summary>
        /// <remarks>详细用法参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_dimension_linear_ref.html#a6a66931963f13658b811e646e8c7b46f">示例</a></remarks>
        /// <param name="dimension"></param>
        /// <param name="point">起点</param>
        /// <param name="path"><see cref="InstancePath"/>起点引用物体</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetStartPoint(IntPtr dimension, Point3D point, IntPtr path);

        /// <summary>
        /// 获取终点
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="point"></param>
        /// <param name="path"><see cref="InstancePath"/>终点引用物体</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetEndPoint(IntPtr dimension, ref Point3D point, out IntPtr path);

        /// <summary>
        /// 设置终点
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="point"></param>
        /// <param name="path"><see cref="InstancePath"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetEndPoint(IntPtr dimension, Point3D point, IntPtr path);

        /// <summary>
        /// 获取X轴
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetXAxis(IntPtr dimension, ref Vector3D axis);

        /// <summary>
        /// 设置X轴
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetXAxis(IntPtr dimension, Vector3D axis);

        /// <summary>
        /// 获取法向
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="normal"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetNormal(IntPtr dimension, ref Vector3D normal);

        /// <summary>
        /// 设置法向
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="normal"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetNormal(IntPtr dimension, Vector3D normal);

        /// <summary>
        /// 获取文字位置，该位置是标注平面上的二维点
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetPosition(IntPtr dimension, ref Point2D position);

        /// <summary>
        /// 设置文字位置
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetPosition(IntPtr dimension, Point2D position);

        /// <summary>
        /// 获取垂直对齐方式
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="alignment"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetVerticalAlignment(IntPtr dimension, out VerticalTextPositionType alignment);

        /// <summary>
        /// 设置垂直对齐方式
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="alignment"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetVerticalAlignment(IntPtr dimension, VerticalTextPositionType alignment);

        /// <summary>
        /// 文字水平对齐方式
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="alignment"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetHorizontalAlignment(IntPtr dimension, out HorizontalTextPositionType alignment);

        /// <summary>
        /// 设置文字水平对齐方式
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="alignment"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearSetHorizontalAlignment(IntPtr dimension, HorizontalTextPositionType alignment);

        /// <summary>
        /// 尺寸标注对齐方式
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="alignment"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetAlignment(IntPtr dimension, out DimensionLinearAlignmentType alignment);

        /// <summary>
        /// 获取文字标注点
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUDimensionLinearGetTextPosition(IntPtr dimension, ref Point3D position);
        #endregion

        /// <summary>
        /// 标注X轴
        /// </summary>
        public Vector3D XAxis
        {
            get
            {
                Vector3D v = new Vector3D();
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetXAxis(Id, ref v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetXAxis(Id, value));
            }
        }

        /// <summary>
        /// 法向
        /// </summary>
        public Vector3D Normal
        {
            get
            {
                Vector3D v = new Vector3D();
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetNormal(Id, ref v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetNormal(Id, value));
            }
        }

        /// <summary>
        /// 标注对齐方式
        /// </summary>
        public DimensionLinearAlignmentType Alignment
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetAlignment(Id, out DimensionLinearAlignmentType d));
                return d;
            }
        }

        /// <summary>
        /// 垂直对齐方式
        /// </summary>
        public VerticalTextPositionType Vertical
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetVerticalAlignment(Id, out VerticalTextPositionType v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetVerticalAlignment(Id, value));
            }
        }

        /// <summary>
        /// 水平对齐方式
        /// </summary>
        public HorizontalTextPositionType Horizontal
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetHorizontalAlignment(Id, out HorizontalTextPositionType v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetHorizontalAlignment(Id, value));
            }
        }

        /// <summary>
        /// 获取文字定位点
        /// </summary>
        public Point3D Location
        {
            get
            {
                Point3D p = new Point3D();
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetTextPosition(Id, ref p));
                return p;
            }
        }

        /// <summary>
        /// 获取文字位置，该位置是标注平面上的二维点
        /// </summary>
        public Point2D Position
        {
            get
            {
                Point2D p = new Point2D();
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetPosition(Id, ref p));
                return p;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetPosition(Id, value));
            }
        }

        internal DimensionLinear(IntPtr id) : base(id)
        {
        }

        /// <summary>
        /// 创建一个尺寸标注
        /// </summary>
        /// <remarks>参数含义参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_dimension_linear_ref.html#a6a66931963f13658b811e646e8c7b46f">示例</a></remarks>
        /// <param name="start"></param>
        /// <param name="startLink"></param>
        /// <param name="end"></param>
        /// <param name="endLink"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public DimensionLinear Create(Point3D start, InstancePath startLink, Point3D end, InstancePath endLink, double offset)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearCreate(out IntPtr id, start, startLink.Id, end, endLink.Id, offset));
            return new DimensionLinear(id);
        }

        /// <summary>
        /// 获取起点信息
        /// </summary>
        /// <param name="start"></param>
        /// <param name="startLink"></param>
        public void GetStartInfo(out Point3D start, out InstancePath startLink)
        {
            start = new Point3D();
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetStartPoint(Id, ref start, out IntPtr path));
            startLink = new InstancePath(path);
        }

        /// <summary>
        /// 设置起点数据
        /// </summary>
        /// <remarks>参数含义参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_dimension_linear_ref.html#a6a66931963f13658b811e646e8c7b46f">示例</a></remarks>
        /// <param name="start"></param>
        /// <param name="startLink"></param>
        public void SetStartInfo(Point3D start, InstancePath startLink)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetStartPoint(Id, start, startLink.Id));
        }

        /// <summary>
        /// 获取终点信息
        /// </summary>
        /// <param name="end"></param>
        /// <param name="endLink"></param>
        public void GetEndInfo(out Point3D end, out InstancePath endLink)
        {
            end = new Point3D();
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearGetEndPoint(Id, ref end, out IntPtr path));
            endLink = new InstancePath(path);
        }

        /// <summary>
        /// 设置终点
        /// </summary>
        /// <remarks>参数含义参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_dimension_linear_ref.html#a6a66931963f13658b811e646e8c7b46f">示例</a></remarks>
        /// <param name="end"></param>
        /// <param name="endLink"></param>
        public void SetEndInfo(Point3D end, InstancePath endLink)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearSetEndPoint(Id, end, endLink.Id));
        }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUDimensionLinearRelease(ref Id));
        }
    }
}